//\description: PhotonBucket class for trax threads to store photon into memory
#ifndef __ATOM_TRACE_PHOTON_BUCKET_H_
#define __ATOM_TRACE_PHOTON_BUCKET_H_

#include "PhotonMap.h"

//#define PHT_BUCK_CAP 100 // total capacity = num_photons/num_threads * photon_bounce_depth
#define PHT_STACK_CAP 10

namespace AtomTrace{

	class PhotonBucket // local stack storage
	{
		Photon phts[PHT_STACK_CAP]; // local temporally bucket in TRAX stack
		int current;
        
        int pht_size;
        int cur_offset; // current global store photon number
        int pm_start_addr;
		//int cur_stack;
	public:
		PhotonBucket();
		//~PhotonBucket();

		const Photon & operator[](int index) const;
		Photon & operator[](int index);

		bool StorePhoton(const Photon & iPht);
		bool StorePhoton(const Color & iflux, const Vector3 & iPos, const Vector3 & idir);

		bool StoreIntoMemory(int addr); // Store all photons to memory even it is empty in stack
        bool StoreIntoMemory(); // Store into memory using atomicinc(2)
		bool StoreNonEmptyIntoMem(int addr);
        bool StoreNonEmptyIntoMem(); // Store into memory using atomicinc(2)

        //Given the first photon address, load photons to fill up the whole bucket,
        // even there are empty photons in the memory
        bool LoadPhotonsFromGM(const int addr);

        // Load num of photons from addr in the memory
        bool LoadPhotonsFromGM(const int addr, const int num);

		inline bool IsEmpty() const;
		inline bool IsFull() const;
		inline void Clear();

		inline const int & GetCurrent() const;
		inline int GetLocalStackSize() const; // size in word
		inline int GetCurrentStackSize() const; // size in word
		inline int GetTotalPhotonCapacity() const;

	};

	bool PhotonBucket::IsFull() const
	{ return (current >= PHT_STACK_CAP); }

	bool PhotonBucket::IsEmpty() const
	{ return (current <= 0); }

	void PhotonBucket::Clear()
	{ current = 0; }

	const int & PhotonBucket::GetCurrent() const
	{ return current; }

	int PhotonBucket::GetLocalStackSize() const
	{ return (PHT_STACK_CAP*sizeof(Photon) / 4); }

	int PhotonBucket::GetCurrentStackSize() const
	{ return (current*sizeof(Photon) / 4); }

	int PhotonBucket::GetTotalPhotonCapacity() const
	{ return PHT_STACK_CAP; }

}

#endif //__ATOM_TRACE_PHOTON_BUCKET_H_
